#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;

int n;
int a[N];

//堆排序
//1）利用堆这种数据结构，能快速找到待排序元素中的最小值或最大值
//2）本质上是优化了选择排序算法
//选择排序：每次找出末排序序列中最小的元素，然后放进有序序列的后面 

void down(int parent, int len)
{
	int child = parent * 2;

	while(child <= len)
	{
		if(child + 1 <= len && a[child + 1] > a[child]) child++;

		if(a[parent] >= a[child]) return;

		swap(a[parent], a[child]);
		parent = child;
		child = parent * 2;
	}
}

void heap_sort()
{
	//1.建堆。从倒数第一个非叶子结点开始，逐渐向下调整
	for(int i = n / 2; i >= 1; i--)
	{
		down(i, n);
	}

	//2.排序。拿堆顶元素和最后一个元素交换，堆大小减1，堆顶元素向下调整
	for(int i = n; i > 1; i--) // 枚举堆里面最后一个元素的位置
	{
		swap(a[1], a[i]);

		down(1, i - 1);
	}
}

int main()
{
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> a[i];	
	
	heap_sort();
	
	for(int i = 1; i <= n; i++) cout << a[i] << " ";	
	
	return 0;
}
